// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.util.ui

import com.intellij.ide.DataManager
import com.intellij.ide.ui.laf.darcula.ui.DarculaButtonPainter
import com.intellij.openapi.actionSystem.ActionToolbar
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.Presentation
import com.intellij.openapi.actionSystem.ex.ActionUtil
import com.intellij.openapi.actionSystem.ex.CustomComponentAction
import com.intellij.openapi.project.DumbAwareAction
import com.intellij.ui.ComponentUtil
import java.awt.Component
import javax.swing.Icon
import javax.swing.JButton
import javax.swing.JComponent
import javax.swing.border.Border

abstract class JButtonAction(text: String?, description: String? = null, icon: Icon? = null)
  : DumbAwareAction(text, description, icon), CustomComponentAction {

  override fun createCustomComponent(presentation: Presentation, place: String): JComponent {
    val button = createButton().apply {
      isFocusable = false
    }.also { button ->
      button.addActionListener {
        val toolbar = ComponentUtil.getParentOfType(ActionToolbar::class.java, button)
        val dataContext = toolbar?.toolbarDataContext ?: DataManager.getInstance().getDataContext(button)
        val action = this@JButtonAction
        val event = AnActionEvent.createFromInputEvent(null, place, presentation, dataContext)

        if (ActionUtil.lastUpdateAndCheckDumb(action, event, true)) {
          ActionUtil.performActionDumbAware(action, event)
        }
      }
    }

    updateButtonFromPresentation(button, presentation)
    val border: Border = JBUI.Borders.empty(0, if (UIUtil.isUnderDefaultMacTheme()) 6 else 4)
    return JBUI.Panels.simplePanel(button).withBorder(border)
  }

  protected open fun createButton(): JButton {
    return object : JButton() {

      override fun updateUI() {
        super.updateUI()
        border = object : DarculaButtonPainter() {
          override fun getBorderInsets(c: Component) = JBUI.insets(0)
        }
      }
    }
  }

  protected fun updateButtonFromPresentation(e: AnActionEvent) {
    val button = UIUtil.findComponentOfType(e.presentation.getClientProperty(CustomComponentAction.COMPONENT_KEY), JButton::class.java)
    if (button != null) updateButtonFromPresentation(button, e.presentation)
  }

  protected open fun updateButtonFromPresentation(button: JButton, presentation: Presentation) {
    button.isEnabled = presentation.isEnabled
    button.isVisible = presentation.isVisible
    button.text = presentation.text
    button.icon = presentation.icon
    button.mnemonic = presentation.mnemonic
    button.displayedMnemonicIndex = presentation.displayedMnemonicIndex
    button.toolTipText = presentation.description
  }
}